package cn.banyingli.banyinglilib.view;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AlertDialog;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.NumberPicker;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Field;
import java.util.Calendar;

import cn.banyingli.banyinglilib.R;
import cn.banyingli.banyinglilib.tools.DateTools;
import cn.banyingli.banyinglilib.tools.StringTools;

/**
 * UI工具类 <BR>
 * 显示Dialog、Toast等
 */
public class UITools {

    /**
     * 显示水平进度条的dialog
     * @param context
     * @param titleResId
     * @param msgResId
     * @return
     */
    public static ProgressDialog showHorizontalProgressDialog(Context context, int titleResId, int msgResId){
        final ProgressDialog progressDialog = new ProgressDialog(context);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setTitle(titleResId);
        progressDialog.setMessage(context.getString(msgResId));
        progressDialog.setProgress(0);
        progressDialog.setMax(100);
        progressDialog.setIndeterminate(false);
        progressDialog.setCancelable(false);
        progressDialog.setCanceledOnTouchOutside(false);
        progressDialog.show();
        return progressDialog;
    }

    /**
     * 显示圆形进度条的dialog
     * @param context
     * @param msgResId
     * @return
     */
    public static ProgressDialog showProgressDialog(Context context, int msgResId){
        ProgressDialog progressDialog = new ProgressDialog(context, ProgressDialog.THEME_HOLO_LIGHT);
        progressDialog.setMessage(context.getString(msgResId));
        progressDialog.setCanceledOnTouchOutside(false);
        progressDialog.setCancelable(false);
        progressDialog.show();
        return progressDialog;
    }

    /**
     * 弹出只有一个按钮的对话框（可指定按钮文字和事件）
     * @param context
     * @param titleResId 标题
     * @param messageResId 信息
     * @param positiveBtnText 确认按钮文字
     * @param positiveListener 确认按钮事件
     */
    public static void showAlertDialog(Context context, int titleResId, int messageResId,
                                       String positiveBtnText, DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleResId)
                .setMessage(messageResId)
                .setPositiveButton(positiveBtnText, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 弹出只有一个按钮的对话框（可指定按钮文字和事件）
     * @param context
     * @param title 标题
     * @param message 信息
     * @param positiveBtnText 确认按钮文字
     * @param positiveListener 确认按钮事件
     */
    public static void showAlertDialog(Context context, String title, String message,
                                       String positiveBtnText, DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title)
                .setMessage(message)
                .setPositiveButton(positiveBtnText, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 弹出只有一个按钮的对话框（只可指定按钮事件）
     * @param context
     * @param titleResId 标题
     * @param messageResId 信息
     * @param positiveListener 确认按钮事件
     */
    public static void showAlertDialog(Context context, int titleResId, int messageResId,
                                       DialogInterface.OnClickListener positiveListener){
        try{
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle(titleResId)
                    .setMessage(messageResId)
                    .setPositiveButton(R.string.lib_ensure, positiveListener)
                    .setCancelable(false)
                    .show();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 弹出只有一个按钮的对话框（只可指定按钮事件）
     * @param context
     * @param title 标题
     * @param message 信息
     * @param positiveListener 确认按钮事件
     */
    public static void showAlertDialog(Context context, String title, String message,
                                       DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title)
                .setMessage(message)
                .setPositiveButton(R.string.lib_ensure, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 弹出只有一个按钮的对话框（点击确定直接关闭对话框）
     * @param context
     * @param titleResId 标题
     * @param messageResId 信息
     */
    public static void showAlertDialog(Context context, int titleResId, int messageResId){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleResId)
                .setMessage(messageResId)
                .setPositiveButton(R.string.lib_ensure, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setCancelable(false)
                .show();
    }

    /**
     * 弹出只有一个按钮的对话框（点击确定直接关闭对话框）
     * @param context
     * @param title 标题
     * @param message 信息
     */
    public static void showAlertDialog(Context context, String title, String message){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title)
                .setMessage(message)
                .setPositiveButton(R.string.lib_ensure, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setCancelable(false)
                .show();
    }

    /**
     * 弹出只有一个按钮的对话框（点击确定直接关闭对话框）
     * @param context
     * @param titleResId 标题
     * @param message 信息
     */
    public static void showAlertDialog(Context context, int titleResId, String message){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleResId)
                .setMessage(message)
                .setPositiveButton(R.string.lib_ensure, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setCancelable(false)
                .show();
    }

    /**
     * 显示确认对话框
     * @param context
     * @param title 标题
     * @param message 信息
     * @param negativeBtnText 取消按钮的文字
     * @param positiveBtnText 确认按钮的文字
     * @param negativeListener 取消按钮的事件
     * @param positiveListener 确认按钮的事件
     */
    public static void showConfirmDialog(Context context, String title, String message,
             String negativeBtnText, String positiveBtnText,
             DialogInterface.OnClickListener negativeListener,
             DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title)
                .setMessage(message)
                .setNegativeButton(negativeBtnText, negativeListener)
                .setPositiveButton(positiveBtnText, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 显示确认对话框
     * @param context
     * @param titleResId 标题
     * @param messageResId 信息
     * @param negativeBtnText 取消按钮的文字
     * @param positiveBtnText 确认按钮的文字
     * @param negativeListener 取消按钮的事件
     * @param positiveListener 确认按钮的事件
     */
    public static void showConfirmDialog(Context context, int titleResId, int messageResId,
                                         String negativeBtnText, String positiveBtnText,
                                         DialogInterface.OnClickListener negativeListener,
                                         DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleResId)
                .setMessage(messageResId)
                .setNegativeButton(negativeBtnText, negativeListener)
                .setPositiveButton(positiveBtnText, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 显示确认对话框
     * @param context
     * @param title 标题
     * @param message 信息
     * @param negativeListener 取消按钮的事件
     * @param positiveListener 确认按钮的事件
     */
    public static void showConfirmDialog(Context context, String title, String message,
             DialogInterface.OnClickListener negativeListener,
             DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title)
                .setMessage(message)
                .setNegativeButton(R.string.lib_cancel, negativeListener)
                .setPositiveButton(R.string.lib_ensure, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 显示确认对话框
     * @param context
     * @param titleResId 标题
     * @param messageResId 信息
     * @param negativeListener 取消按钮的事件
     * @param positiveListener 确认按钮的事件
     */
    public static void showConfirmDialog(Context context, int titleResId, int messageResId,
                                         DialogInterface.OnClickListener negativeListener,
                                         DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleResId)
                .setMessage(messageResId)
                .setNegativeButton(R.string.lib_cancel, negativeListener)
                .setPositiveButton(R.string.lib_ensure, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 显示确认对话框
     * @param context
     * @param title 标题
     * @param message 信息
     * @param positiveListener 确认按钮的事件
     */
    public static void showConfirmDialog(Context context, String title, String message,
                                         DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title)
                .setMessage(message)
                .setNegativeButton(R.string.lib_cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setPositiveButton(R.string.lib_ensure, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 显示确认对话框
     * @param context
     * @param titleResId 标题
     * @param messageResId 信息
     * @param positiveListener 确认按钮的事件
     */
    public static void showConfirmDialog(Context context, int titleResId, int messageResId,
                                         DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleResId)
                .setMessage(messageResId)
                .setNegativeButton(R.string.lib_cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setPositiveButton(R.string.lib_ensure, positiveListener)
                .setCancelable(false)
                .show();
    }

    /**
     * 显示单选列表对话框
     * @param context
     * @param title
     * @param data 选项数组
     * @param listener
     */
    public static void showSingleChoiceDialog(Context context, String title, String[] data, DialogInterface.OnClickListener listener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title)
                .setItems(data, listener)
                .show();
    }

    /**
     * 显示多选列表对话框
     * @param context
     * @param title
     * @param data 选项数组
     * @param checkedItems 选择情况数组
     * @param listener
     * @param negativeListener
     * @param positiveListener
     */
    public static void showMultiChoiceDialog(Context context, String title, String[] data,boolean[] checkedItems,
                                             DialogInterface.OnMultiChoiceClickListener listener,
                                             DialogInterface.OnClickListener negativeListener,
                                             DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title)
                .setMultiChoiceItems(data, checkedItems, listener)
                .setNegativeButton(R.string.lib_cancel, negativeListener)
                .setPositiveButton(R.string.lib_ensure, positiveListener)
                .show();
    }

    /**
     * 显示多选列表对话框
     * @param context
     * @param titleResId
     * @param data 选项数组
     * @param checkedItems 选择情况数组
     * @param listener
     * @param negativeListener
     * @param positiveListener
     */
    public static void showMultiChoiceDialog(Context context, int titleResId, String[] data,boolean[] checkedItems,
                                             DialogInterface.OnMultiChoiceClickListener listener,
                                             DialogInterface.OnClickListener negativeListener,
                                             DialogInterface.OnClickListener positiveListener){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleResId)
                .setMultiChoiceItems(data, checkedItems, listener)
                .setNegativeButton(R.string.lib_cancel, negativeListener)
                .setPositiveButton(R.string.lib_ensure, positiveListener)
                .show();
    }


    /**
     * 显示日期选择框
     * @param activity
     * @param titleResId 标题资源ID
     * @param defaultDate 默认日期
     * @param listener 返回的日期格式是 yyyy-mm-dd
     */
    public static void showDatePicker(Activity activity, int titleResId, String defaultDate, final IDatePickerListener listener){
        LayoutInflater inflater = activity.getLayoutInflater();
        View dateView = inflater.inflate(R.layout.dialog_datepicker_layout, null);
        final NumberPicker yearPicker = dateView.findViewById(R.id.yearNP);
        final NumberPicker monthPicker = dateView.findViewById(R.id.monthNP);
        final NumberPicker dayPicker = dateView.findViewById(R.id.dayNP);

        Calendar calendar = DateTools.str2Calendar(defaultDate, "yyyy-MM-dd");
        if(null == calendar){
            calendar = DateTools.calendar();
        }
        setDatePicker(calendar, yearPicker, monthPicker, dayPicker);

        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle(titleResId)
                .setNegativeButton(R.string.lib_cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onDateSelectCancel();
                    }
                })
                .setPositiveButton(R.string.lib_ensure, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onDateSelected(yearPicker.getValue() + "-"
                                + StringTools.addZeroForNumLeft(String.valueOf(monthPicker.getValue()), 2) + "-"
                                + StringTools.addZeroForNumLeft(String.valueOf(dayPicker.getValue()), 2));
                    }
                })
                .setView(dateView)
                .show();
    }

    /**
     * 显示日期选择框
     * @param activity
     * @param titleResId 标题资源ID
     * @param defaultDate 默认日期
     * @param listener 返回的日期格式是 yyyy-mm-dd HH:mm:dd
     */
    public static void showDateTimePicker(Activity activity, int titleResId, String defaultDate, final IDatePickerListener listener){
        LayoutInflater inflater = activity.getLayoutInflater();
        View dateView = inflater.inflate(R.layout.dialog_datetimepicker_layout, null);
        final NumberPicker yearPicker = dateView.findViewById(R.id.yearNP);
        final NumberPicker monthPicker = dateView.findViewById(R.id.monthNP);
        final NumberPicker dayPicker = dateView.findViewById(R.id.dayNP);
        final NumberPicker hPicker = dateView.findViewById(R.id.hNP);
        final NumberPicker mPicker = dateView.findViewById(R.id.mNP);
        final NumberPicker sPicker = dateView.findViewById(R.id.sNP);

        Calendar calendar = DateTools.str2Calendar(defaultDate, "yyyy-MM-dd HH:mm:ss");
        if(null == calendar){
            calendar = DateTools.calendar();
        }
        setDatePicker(calendar, yearPicker, monthPicker, dayPicker);
        setTimePicker(calendar, hPicker, mPicker, sPicker);
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle(titleResId)
                .setNegativeButton(R.string.lib_cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onDateSelectCancel();
                    }
                })
                .setPositiveButton(R.string.lib_ensure, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onDateSelected(yearPicker.getValue() + "-"
                                + StringTools.addZeroForNumLeft(String.valueOf(monthPicker.getValue()), 2) + "-"
                                + StringTools.addZeroForNumLeft(String.valueOf(dayPicker.getValue()), 2) + " "
                                + StringTools.addZeroForNumLeft(String.valueOf(hPicker.getValue()), 2) + ":"
                                + StringTools.addZeroForNumLeft(String.valueOf(mPicker.getValue()), 2) + ":"
                                + StringTools.addZeroForNumLeft(String.valueOf(sPicker.getValue()), 2));
                    }
                })
                .setView(dateView)
                .show();
    }

    /**
     * 设置DatePicker
     * @param calendar
     * @param yearPicker
     * @param monthPicker
     * @param dayPicker
     */
    private static void setDatePicker(Calendar calendar, final NumberPicker yearPicker, final NumberPicker monthPicker,
                                       final NumberPicker dayPicker){
        final int year = calendar.get(Calendar.YEAR);
        final int month = calendar.get(Calendar.MONTH) + 1;
        yearPicker.setMaxValue(year + 100);
        yearPicker.setMinValue(year - 100);
        monthPicker.setMaxValue(12);
        monthPicker.setMinValue(1);
        dayPicker.setMaxValue(DateTools.daysOfMonth(year, month));
        dayPicker.setMinValue(1);
        yearPicker.setValue(year);
        monthPicker.setValue(month);
        dayPicker.setValue(calendar.get(Calendar.DAY_OF_MONTH));
        yearPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                if(2 == monthPicker.getValue()){
                    int daysOfMonth = DateTools.daysOfMonth(newVal, monthPicker.getValue());
                    dayPicker.setMaxValue(daysOfMonth);
                }
            }
        });
        monthPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                int daysOfMonth = DateTools.daysOfMonth(yearPicker.getValue(), newVal);
                dayPicker.setMaxValue(daysOfMonth);
            }
        });
    }

    /**
     * 设置时间选择器
     * @param calendar
     * @param hPicker
     * @param mPicker
     * @param sPicker
     */
    private static void setTimePicker(Calendar calendar, final NumberPicker hPicker, final NumberPicker mPicker,
                                      final NumberPicker sPicker){
        hPicker.setMaxValue(59);
        hPicker.setMinValue(0);
        mPicker.setMaxValue(59);
        mPicker.setMinValue(0);
        sPicker.setMaxValue(59);
        sPicker.setMinValue(0);
        hPicker.setValue(calendar.get(Calendar.HOUR_OF_DAY));
        mPicker.setValue(calendar.get(Calendar.MINUTE));
        sPicker.setValue(calendar.get(Calendar.SECOND));
    }

    public static void showLongToast(Context context, String message){
        Toast.makeText(context, message, Toast.LENGTH_LONG).show();
    }

    public static void showLongToast(Context context, int messageResId){
        Toast.makeText(context, messageResId, Toast.LENGTH_LONG).show();
    }

    public static void showShortToast(Context context, String message){
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
    }

    public static void showShortToast(Context context, int messageResId){
        Toast.makeText(context, messageResId, Toast.LENGTH_SHORT).show();
    }

    /**
     * 调节tablayout指示线宽度 Api28以下
     * @param tabs
     * @param leftDip
     * @param rightDip
     */
    public static void setTabLayoutIndicator(final TabLayout tabs, final int leftDip, final int rightDip) {
        tabs.post(new Runnable() {
            @Override
            public void run() {
                Class<?> tabLayout = tabs.getClass();
                Field tabStrip = null;
                try {
                    tabStrip = tabLayout.getDeclaredField("mTabStrip");
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }

                tabStrip.setAccessible(true);
                LinearLayout llTab = null;
                try {
                    llTab = (LinearLayout) tabStrip.get(tabs);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

                int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
                int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());

                for (int i = 0; i < llTab.getChildCount(); i++) {
                    View child = llTab.getChildAt(i);
                    child.setPadding(0, 0, 0, 0);
                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
                    params.leftMargin = left;
                    params.rightMargin = right;
                    child.setLayoutParams(params);
                    child.invalidate();
                }
            }
        });

    }

    /**
     * 调节tablayout指示线宽度 Api28之后
     * @param tabLayout
     * @param margin
     */
    public static void setTabLayoutIndicator28(@NonNull final TabLayout tabLayout, final int margin) {
        tabLayout.post(new Runnable() {
            @Override
            public void run() {
                try {
                    // 拿到tabLayout的slidingTabIndicator属性
                    Field slidingTabIndicatorField = tabLayout.getClass().getDeclaredField("slidingTabIndicator");
                    slidingTabIndicatorField.setAccessible(true);
                    LinearLayout mTabStrip = (LinearLayout) slidingTabIndicatorField.get(tabLayout);
                    for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                        View tabView = mTabStrip.getChildAt(i);
                        //拿到tabView的mTextView属性
                        Field textViewField = tabView.getClass().getDeclaredField("textView");
                        textViewField.setAccessible(true);
                        TextView mTextView = (TextView) textViewField.get(tabView);
                        tabView.setPadding(0, 0, 0, 0);
                        // 因为想要的效果是字多宽线就多宽，所以测量mTextView的宽度
                        int width = mTextView.getWidth();
                        if (width == 0) {
                            mTextView.measure(0, 0);
                            width = mTextView.getMeasuredWidth();
                        }
                        // 设置tab左右间距,注意这里不能使用Padding,因为源码中线的宽度是根据tabView的宽度来设置的
                        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
                        params.width = width;
                        params.leftMargin = margin;
                        params.rightMargin = margin;
                        tabView.setLayoutParams(params);
                        tabView.invalidate();
                    }
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Darkens a color by a given factor.
     *
     * @param color the color to darken
     * @param factor The factor to darken the color.
     * @return darker version of specified color.
     */
    public static int darker(int color, float factor) {
        return Color.argb(Color.alpha(color), Math.max((int) (Color.red(color) * factor), 0),
                Math.max((int) (Color.green(color) * factor), 0), Math.max((int) (Color.blue(color) * factor), 0));
    }

    /**
     * Lightens a color by a given factor.
     *
     * @param color The color to lighten
     * @param factor The factor to lighten the color. 0 will make the color unchanged. 1 will make the
     * color white.
     * @return lighter version of the specified color.
     */
    public static int lighter(int color, float factor) {
        int red = (int) ((Color.red(color) * (1 - factor) / 255 + factor) * 255);
        int green = (int) ((Color.green(color) * (1 - factor) / 255 + factor) * 255);
        int blue = (int) ((Color.blue(color) * (1 - factor) / 255 + factor) * 255);
        return Color.argb(Color.alpha(color), red, green, blue);
    }

    /**
     * Check if layout direction is RTL
     *
     * @param context the current context
     * @return {@code true} if the layout direction is right-to-left
     */
    public static boolean isRtl(Context context) {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
                && context.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
    }
}
